package gov.pbc.gx.nn.pz.dao;

import gov.pbc.gx.nn.pz.entity.BaseEntity;

import java.io.Serializable;
import java.util.Date;

import org.hibernate.Session;

import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.bdf2.core.orm.hibernate.HibernateDao;
import com.bstek.bdf2.core.orm.hibernate.ISessionCallback;
import com.bstek.dorado.util.proxy.ProxyBeanUtils;

/**
 * Hibernate操作的基础类，所有的支持Hibernate操作的类都要继承该类
 * 
 * @author Louis
 * 
 */
public abstract class AbstractHibernateDao extends HibernateDao {

	public Serializable save(final BaseEntity entity) {
		return this.doInHibernateSession(new ISessionCallback<Serializable>() {

			@Override
			public Serializable doInSession(Session session) {
				entity.setCreateUser(ContextHolder.getLoginUserName());
				entity.setCreateDate(new Date());
				return session.save(entity);
			}

		});
	}

	public void update(final BaseEntity entity) {
		this.doInHibernateSession(new ISessionCallback<Void>() {

			@Override
			public Void doInSession(Session session) {
				entity.setUpdateDate(new Date());
				entity.setUpdateUser(ContextHolder.getLoginUserName());
				session.update(entity);
				return null;
			}

		});
	}

	public void delete(final BaseEntity entity) {
		this.doInHibernateSession(new ISessionCallback<Void>() {

			@Override
			public Void doInSession(Session session) {
				entity.setUpdateDate(new Date());
				entity.setUpdateUser(ContextHolder.getLoginUserName());
				entity.setInvalid(true);
				session.update(entity);
				return null;
			}

		});
	}

	@SuppressWarnings("unchecked")
	public void delete(final String id, String className) throws Exception {
		final Class<?> clazz = Class.forName(className);
		if (BaseEntity.class.isAssignableFrom(clazz)) {
			this.delete(id, (Class<? extends BaseEntity>) clazz);
		}
	}

	public void delete(final String id, final Class<? extends BaseEntity> clazz) {
		this.doInHibernateSession(new ISessionCallback<Void>() {

			@Override
			public Void doInSession(Session session) {
				Class<?> type = clazz;
				if (ProxyBeanUtils.isProxy(clazz)) {
					type = ProxyBeanUtils.getProxyTargetType(clazz);
				}
				BaseEntity entity = (BaseEntity) session.get(type, id);
				if (entity != null) {
					entity.setUpdateDate(new Date());
					entity.setUpdateUser(ContextHolder.getLoginUserName());
					entity.setInvalid(true);
					session.update(entity);
				}
				return null;
			}

		});
	}
}
